﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using StockModel;
using Visiblox.Charts;

namespace FullDayStrategyPlugin
{
	internal partial class DailyChart : UserControl
	{
		#region Attributes

		private IEnumerable<Quotation> _quotations;
		private IEnumerable<Operation> _operations;

		#endregion

		#region Properties

		public DataSeries<DateTime, decimal> OpenPercentageValues { get; private set; }
		public DataSeries<DateTime, decimal> BidAskValues { get; private set; }

		public DateTime Day
		{
			set
			{
				this.Chart.Title = value.Date.ToShortDateString();
			}
		}

		#endregion

		#region Public Methods

		public DailyChart()
		{
			this.OpenPercentageValues = new DataSeries<DateTime, decimal>("OpenPercentageValues");
			this.BidAskValues = new DataSeries<DateTime, decimal>("Bid - Ask values");
			
			InitializeComponent();
		}

		public void Initialize(IEnumerable<Operation> operations, IEnumerable<Quotation> quotations, DateTime day)
		{
			_operations = operations;
			_quotations = quotations;

			this.Day = day;

			this.GenerateData();
		}

		#endregion

		#region Private Methods

		private void GenerateData()
		{
			DailyChartPoints points = this.GenerateChartPoints();
			
			this.BidAskValues.AddRange(points.BidAskValues);

			foreach (DataPoint<DateTime, decimal> operation in points.Operations)
			{
				this.Chart.Annotations.Add(new VerticalLineAnnotation(new DataPoint<DateTime, Decimal>(operation.X, operation.Y)) { AnnotationElementStyle = (Style)Resources["OperationVerticalLineStyle"] });
				this.Chart.Annotations.Add(new HorizontalLineAnnotation(new DataPoint<DateTime, Decimal>(operation.X, operation.Y)) { AnnotationElementStyle = (Style)Resources["OperationHorizontalLineStyle"] });
			}

			this.Chart.Series[0].DataSeries = this.BidAskValues;
		}

		private DailyChartPoints GenerateChartPoints()
		{
			DailyChartPoints result = new DailyChartPoints();

			Quotation openQuotation = _quotations.FirstOrDefault(q => q.Volume > 0 && q.Type != QuoteType.OpeningBid && q.Type != QuoteType.Closed);
			
			if (openQuotation != null)
			{
				decimal firstValue = openQuotation.Value;

				foreach (Quotation quotation in _quotations)
				{
					Dictionary<object, decimal> data = new Dictionary<object, decimal>();
					data.Add(BandSeries.Lower, quotation.Buyers[0].Value * 100 / firstValue - 100);
					data.Add(BandSeries.Upper, quotation.Sellers[0].Value * 100 / firstValue - 100);

					result.BidAskValues.Add(new MultiValuedDataPoint<DateTime, decimal>(quotation.Date, data));
				}

				foreach (Operation operation in _operations)
				{
					// ReSharper disable PossibleInvalidOperationException
					result.Operations.Add(new DataPoint<DateTime, decimal>(operation.BuyDate, 100 - operation.BuyPrice * 100 / firstValue));
					result.Operations.Add(new DataPoint<DateTime, decimal>(operation.SellDate, 100 - operation.SellPrice * 100 / firstValue));
					// ReSharper restore PossibleInvalidOperationException
				}
			}

			return result;
		}

		#endregion
	}
}
